package com.ruoyi.framework.aspectj;

import com.ruoyi.common.annotation.ConvertField;
import com.ruoyi.common.annotation.ConvertFieldItem;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.enums.ConvertType;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysUserService;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 字段转换处理
 *
 * @author yr
 */
@Aspect
@Component
public class ConvertFieldAspect {

    @Autowired
    private ISysDeptService iSysDeptService;
    @Autowired
    private ISysUserService iSysUserService;
    @Autowired
    private ISysDictDataService dictDataService;

    @AfterReturning(pointcut = "@annotation(convertField)", returning = "res")
    public void afterReturning(ConvertField convertField, Object res) throws Exception {
        ConvertFieldItem[] convertFieldItems = convertField.value();
        for (ConvertFieldItem convertFieldItem : convertFieldItems) {
            //判断返回值是否是list集合
            if (res instanceof java.util.List) {
                List<Object> list = (List<Object>) res;
                List<SysDictData> dictDataList = new ArrayList<>();
                //判断是否是字典类型,如果是则先查询字典列表，减少内部查询数据库次数
                if (convertFieldItem.type() == ConvertType.DICT) {
                    String dictType = convertFieldItem.dictType();
                    //判断是否是动态的字典类型
                    if (!dictType.contains("#{")) {
                        dictDataList = dictDataService.selectDictListByType(convertFieldItem.dictType());
                    }
                }
                for (Object item : list) {
                    if (convertFieldItem.type() == ConvertType.DICT && dictDataList.size() == 0) {
                        String fieldName = convertFieldItem.dictType();
                        if (fieldName.contains("#{")) {
                            fieldName = fieldName.substring(2, fieldName.length() - 1);
                            String dictType = (String) getFieldValueByName(item, fieldName);
                            dictDataList = dictDataService.selectDictListByType(dictType);
                        }
                    }
                    handleRes(item, convertFieldItem, dictDataList);
                }
            } else {
                handleRes(res, convertFieldItem, null);
            }
        }


    }

    /**
     * 处理返回值
     *
     * @param res          原数据
     * @param dictDataList 字典数据列表
     */
    public void handleRes(Object res, ConvertFieldItem convertFieldItem, List<SysDictData> dictDataList) {
        Class<?> aClass = res.getClass();
        Field field;//字段1
        Object fieldValue;//字段1的值
        try {
            field = getFieldByName(aClass, convertFieldItem.fieldName());
            field.setAccessible(true);
            fieldValue = field.get(res);
            if (fieldValue != null) {
                ConvertType type = convertFieldItem.type();
                switch (type) {
                    case DEPT:
                        String deptName = iSysDeptService.selectDeptById((Long) fieldValue).getDeptName();
                        setFieldValue(res, aClass, field, convertFieldItem.assistFieldName(), deptName);
                        break;
                    case USER:
                        String nickName = iSysUserService.selectUserById((Long) fieldValue).getNickName();
                        setFieldValue(res, aClass, field, convertFieldItem.assistFieldName(), nickName);
                        break;
                    case DICT:
                        if (dictDataList != null && dictDataList.size() > 0) {
                            for (SysDictData dictData : dictDataList) {
                                if (dictData.getDictValue().equals(fieldValue)) {
                                    setFieldValue(res, aClass, field, convertFieldItem.assistFieldName(), dictData.getDictLabel());
                                    break;
                                }
                            }
                        } else {
                            String dictType = convertFieldItem.dictType();
                            String dictLabel = dictDataService.selectDictLabel(dictType, (String) fieldValue);
                            setFieldValue(res, aClass, field, convertFieldItem.assistFieldName(), dictLabel);
                        }
                        break;
                    case CONSTANT:
                        String[] constantValue = convertFieldItem.constantValue();
                        Map<String, String> map = new HashMap<>();
                        for (String value : constantValue) {
                            String[] parts = value.split(":");
                            map.put(parts[0], parts[1]);
                        }
                        setFieldValue(res, aClass, field, convertFieldItem.assistFieldName(), map.get(fieldValue.toString()));
                        break;
                    default:
                        throw new IllegalArgumentException("不支持的转换类型: " + type);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 设置字段值
     *
     * @param t          原数据
     * @param itemClass  原数据类
     * @param field      字段
     * @param fieldName2 转换后的字段名
     * @param value      新值
     */
    public <V> void setFieldValue(Object t, Class<?> itemClass, Field field, String fieldName2, V value) throws Exception {
        if (fieldName2.isEmpty()) {
            field.set(t, value);
        } else {
            Field field2 = getFieldByName(itemClass, fieldName2);
            field2.setAccessible(true);
            field2.set(t, value);
        }
    }

    /**
     * 获取对象指定的元素
     *
     * @param aClass 对象
     * @param name   字段名
     */
    private Field getFieldByName(Class<?> aClass, String name) throws Exception {
        Field[] fields = aClass.getDeclaredFields();
        for (Field field : fields) {
            if (name.equals(field.getName())) {
                return field;
            }
        }
        Class<?> superclass = aClass.getSuperclass();
        if (Object.class == aClass.getSuperclass()) {
            throw new Exception("查找字段【" + name + "】失败");
        }
        return getFieldByName(superclass, name);
    }

    /**
     * 获取对象指定的元素的值
     *
     * @param res  原数据
     * @param name 字段名
     */
    private Object getFieldValueByName(Object res, String name) throws Exception {
        Field fieldByName = getFieldByName(res.getClass(), name);
        fieldByName.setAccessible(true);
        return fieldByName.get(res);
    }


}
